using System.Data.SqlTypes;
using Admin2024.Domain.Entity.System;
using Admin2024.Domain.IDomainService;
using Admin2024.Domain.Interface;
using Admin2024.Domain.ObjValue;
using Microsoft.AspNetCore.Http;
using Microsoft.AspNetCore.Mvc;

namespace Admin2024.Domain.DomainService.System;

public class FileUploadService : IFileUploadService
{
    private readonly IRepository<AppFileUpload> _appFileRepository;
    private readonly UploadFilesSettings _uploadFilesSettings;

    public FileUploadService(IRepository<AppFileUpload> appFileRepository, UploadFilesSettings uploadFilesSettings)
    {
        _appFileRepository = appFileRepository;
        _uploadFilesSettings = uploadFilesSettings;
    }

    public async Task<DomainResult<FileContentResult>> GetFileByIdAsync(Guid appFileId)
    {
        var file = await _appFileRepository.GetByIdAsync(appFileId);
        if (file == null)
        {
            //MediaTypeHeaderValue 类的构造函数接受一个字符串参数，用于指定内容类型的字符串表示形式。可以使用标准的 MIME 类型字符串，例如 "application/pdf" 或 "image/jpeg"。
            //    两种返回，一种是没有找到总是返回空的图片，另一个是返回提示
            // return DomainResult<FileContentResult>.Success(new FileContentResult([],"image/jpeg"));
            return DomainResult<FileContentResult>.Error("文件记录不存在，请确认后重试");

        }
        //获取当前应用程序的工作目录。工作目录是应用程序在运行时所处的目录，通常是应用程序的根目录。
        var currentPath = Directory.GetCurrentDirectory();
        //将当前工作目录和 file.RelativePath组合在一起，形成一个完整的文件路径。
        var fullPath = Path.Combine(currentPath, file.RelativePath);

        if (File.Exists(fullPath))
        {
            //使用 FileStream 类创建一个文件流对象 stream，并将文件路径 fullPath 和打开模式 FileMode.Open 作为参数传递给构造函数。FileMode.Open 表示以只读方式打开文件。
            var stream = new FileStream(fullPath, FileMode.Open);
            var contentType = file.ContentType;
            var bytes = new byte[stream.Length];
            //将文件流中的内容读取到字节数组 bytes 中。
            stream.Read(bytes, 0, bytes.Length);
            // 关闭文件流并返回文件内容
            stream.Close();

            return DomainResult<FileContentResult>.Success(new FileContentResult(bytes, contentType));
        }
        else
        {
            // return DomainResult<FileContentResult>.Success(new FileContentResult([],"image/jpeg"));
            return DomainResult<FileContentResult>.Error("文件不存在，请确认后重试");
        }

    }

    public async Task<DomainResult<AppFileUpload>> UploadFilesAsync(IFormFile file)
    {
        if (!FileValidation(file, _uploadFilesSettings))
        {
            return DomainResult<AppFileUpload>.Error("文件上传失败，文件类型或大小不符合要求。");
        }

        //获取当前应用的完整路径
        var filePath = Directory.GetCurrentDirectory();
        var configPath = _uploadFilesSettings.FilePath;

        //最终存放文件的完整路径
        var preFullPath = Path.Combine(filePath, configPath);

        // 如果路径不存在，则创建
        if (!Directory.Exists(preFullPath))
        {
            Directory.CreateDirectory(preFullPath);
        }

        if(file.Length>0){
             var fileName = file.FileName;
                var extName = fileName[fileName.LastIndexOf(".")..];//extName包含了“.”
                var rndName = Guid.NewGuid().ToString("N") + extName;
                var tempPath = Path.Combine(configPath, rndName).Replace("\\", "/");
                using (var stream = new FileStream(Path.Combine(filePath, tempPath), FileMode.Create))
                {
                   await file.CopyToAsync(stream);
                };
            var tmpFile = new AppFileUpload
            {
                Id = Guid.NewGuid(),
                FileName = file.FileName,
                ContentType = file.ContentType,
                RelativePath = tempPath
            };
            await _appFileRepository.CreateAsync(tmpFile);
          return DomainResult<AppFileUpload>.Success(tmpFile);


        }else{
            return DomainResult<AppFileUpload>.Error("请重试");
        }

           
   
             

    }



private static bool FileValidation(IFormFile file, UploadFilesSettings uploadFilesSettings)
{
    var allowExtensions = uploadFilesSettings.AllowFileExtension;
    var maxFileSize = ConvertToBytes(uploadFilesSettings.MaxFileSize);

    if(file.Length>maxFileSize){
        return false;
    }
    var fileName = Path.GetExtension(file.FileName).ToLower().TrimStart('.');
    if(!allowExtensions.Contains(fileName)){
        return false;
    }

    return true;
}

// 转换配置中的单位为字节单位
public static long ConvertToBytes(string valueWithUnit)
{
    // 去除可能的空格
    valueWithUnit = valueWithUnit.Trim();

    // 找到单位的位置
    int unitIndex = valueWithUnit.Length - 1;

    // 确定单位并转换为字节
    long bytes = 0;
    bytes = valueWithUnit[unitIndex].ToString().ToUpper() switch
    {
        "K" => Convert.ToInt64(valueWithUnit[..unitIndex]) * 1024,
        "M" => Convert.ToInt64(valueWithUnit[..unitIndex]) * 1024 * 1024,
        "G" => Convert.ToInt64(valueWithUnit[..unitIndex]) * 1024 * 1024 * 1024,
        _ => Convert.ToInt64(valueWithUnit),// 如果没有单位，默认认为是字节
    };
    return bytes;
}
}
 
